package org.asiainfo.audit.consumer;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.asiainfo.audit.domain.bo.TbAuditMessageBo;
import org.asiainfo.audit.service.TbAuditMessageService;
import org.asiainfo.common.core.mq.Messaging;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 消费 mybatis日志
 *
 * @author dotor-ww
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class LogStreamConsumer {

    private final TbAuditMessageService auditMessageService;

    /**
     * 消息缓存
     */
    private final List<TbAuditMessageBo> messageCaches = new ArrayList<>();

    /**
     * 批量插入阈值
     */
    private final int BATCH_SIZE = 10;

    /**
     * 注册消费log bean
     */
    @Bean
    Consumer<Messaging> log() {
        log.info("\u001B[35m" + " Mybatis消费日志状态->初始化订阅成功！ \u001B[0m");
        return msg -> {
            TbAuditMessageBo messageBo = JSONUtil.toBean(msg.getMsgText(), TbAuditMessageBo.class);
            Map<String, Object> metas = messageBo.getMetas();
            // 判断是否有附加元素
            if (CollUtil.isNotEmpty(metas)) {
                handleTbAuditMessageBo(messageBo, metas);
                messageCaches.add(messageBo);
                if (messageCaches.size() > BATCH_SIZE) {
                    batchTbAuditMessageBoToDataBase(messageCaches);
                }
            }
        };
    }

    /**
     * 处理审计信息
     *
     * @param messageBo 审计信息
     * @param metas     附件元素
     */
    private void handleTbAuditMessageBo(TbAuditMessageBo messageBo, Map<String, Object> metas) {
        String userName = MapUtil.getStr(metas, "userName");
        messageBo.setUserName(userName);
        Long userId = MapUtil.getLong(metas, "userId");
        messageBo.setUserId(userId);
    }

    /**
     * 批量插入审计信息
     *
     * @param messageBos 审计信息
     */
    private void batchTbAuditMessageBoToDataBase(List<TbAuditMessageBo> messageBos) {
        if(messageBos.size() > 0){
            auditMessageService.insertBatchByBo(messageBos);
            messageCaches.clear();
        }
    }
}
